#if !defined(__TGEXTENSIONMODULE_H__)
#define __TGEXTENSIONMODULE_H__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class TGExtensionModule
{
public:
	TGExtensionModule();
	~TGExtensionModule();

public:
	BOOL AttachInstance(HINSTANCE hInst);
	void DetachInstance();

	BOOL Attached();
	HINSTANCE ModuleResourceInstance();

private:
	BOOL m_bAttached;
	HINSTANCE m_hModuleResource;
	AFX_EXTENSION_MODULE m_module;
};

inline TGExtensionModule::TGExtensionModule()
	: m_bAttached(FALSE), m_hModuleResource(NULL)
{
    m_module.bInitialized = FALSE;
    m_module.hModule = NULL;
    m_module.hResource = NULL;
    m_module.pFirstSharedClass = NULL;
    m_module.pFirstSharedFactory = NULL;
}

inline TGExtensionModule::~TGExtensionModule()
{
}

inline BOOL TGExtensionModule::Attached()
{
    return m_bAttached;
}

inline BOOL TGExtensionModule::AttachInstance(HINSTANCE hInst)
{
    if (m_bAttached)
        return FALSE;

    m_bAttached = AfxInitExtensionModule(m_module, hInst);
    if (m_bAttached)
	{
        m_hModuleResource = hInst;
        new CDynLinkLibrary(m_module);
    }

    return m_bAttached;
}

inline void TGExtensionModule::DetachInstance()
{
    if (m_bAttached)
	{
        AfxTermExtensionModule(m_module);
        m_bAttached = FALSE;
    }
}

inline HINSTANCE TGExtensionModule::ModuleResourceInstance()
{
    return m_hModuleResource;
}


class TGModuleResourceOverride
{
public:
	TGModuleResourceOverride();
	TGModuleResourceOverride(HINSTANCE hInst);
	~TGModuleResourceOverride();

	static HINSTANCE ModuleResourceInstance();

private:
	HINSTANCE m_hOldResource;
	static  TGExtensionModule& m_module;
};

inline TGModuleResourceOverride::TGModuleResourceOverride()
{
	m_hOldResource = AfxGetResourceHandle();
	AfxSetResourceHandle(m_module.ModuleResourceInstance());
}

inline TGModuleResourceOverride::TGModuleResourceOverride(HINSTANCE hInst)
{
	m_hOldResource = AfxGetResourceHandle();
	AfxSetResourceHandle(hInst ? hInst : m_module.ModuleResourceInstance());
}

inline TGModuleResourceOverride::~TGModuleResourceOverride ()
{
	if (m_hOldResource != NULL)
		AfxSetResourceHandle(m_hOldResource);
}

inline HINSTANCE TGModuleResourceOverride::ModuleResourceInstance()
{
	return m_module.ModuleResourceInstance();
}

#define TG_DECLARE_EXTENSION_MODULE(exm)
	extern TGExtensionModule exm;

#define TG_IMPLEMENT_EXTENSION_MODULE(exm)      \
    TGExtensionModule exm;                     \
    TGExtensionModule& TGModuleResourceOverride::m_module = exm;

#define theResourceHandle TGModuleResourceOverride::ModuleResourceInstance()

#endif // !defined(__TGEXTENSIONMODULE_H__)
